const router = require('koa-router')();
const db2 = require('../db/db2');

router.prefix('/chat')

/**
 * 添加前搜索用户
 * @param {string} val 要添加的用户名或uid
 */
router.get('/searchBeforeAdd', async (ctx, next) => {
  const userName = ctx.request.header.username;
  const { val } = ctx.query;
  if (!val) {
    ctx.body = {
      code: '0002',
      message: '缺少搜索参数',
      data: false
    }
    return;
  }
  const r0 = await db2.find('users', { $or: [{ userName: val }, { uid: parseInt(val) }] });
  if (!r0 || r0.length === 0) {
    ctx.body = {
      code: '0000',
      message: '搜索的用户不存在',
      data: {
        isExist: false,
      }
    }
    return;
  }
  const info = {
    userName: r0[0].userName,
    uid: r0[0].uid,
    avatarUrl: r0[0].avatarUrl,
    sex: r0[0].sex,
    nick: r0[0].nick
  };
  const r1 = await db2.find('chat', { userName });
  if (!r1 || r1.length === 0) {
    ctx.body = {
      code: '0000',
      message: '该用户不是好友',
      data: Object.assign({}, {
        isExist: true,
        isFriend: false,
      }, info)
    }
    return;
  }
  const friend = r1[0].friends.find(item => item.userName === val || item.uid === parseInt(val));
  if (!friend) {
    ctx.body = {
      code: '0000',
      message: '该用户不是好友',
      data: Object.assign({}, {
        isExist: true,
        isFriend: false,
      }, info)
    }
    return;
  }
  ctx.body = {
    code: '0000',
    message: '该用户是好友',
    data: Object.assign({}, {
      isExist: true,
      isFriend: true,
    }, info)
  }
})

/**
 * 自动添加自己为好友
 */
router.get('/addSelfFriend', async (ctx, next) => {
  const userName = ctx.request.header.username;
  const r1 = await db2.find('chat', { userName });
  const r2 = await db2.find('users', { userName });
  if (!r1 || r1.length === 0) {
    await db2.addOne('chat', {
      userName,
      uid: r2[0].uid,
      sex: r2[0].sex,
      avatarUrl: r2[0].avatarUrl,
      feelingWords: '', // webchat签名状态
      applyOtherUserFriends: [], // 申请添加别人为好友
      groups: [], // 群组列表
      friends: [
        // 自己本身就是自己的好友
        {
          userName,
          uid: r2[0].uid,
          sex: r2[0].sex,
          avatarUrl: r2[0].avatarUrl,
          addDate: Date.now(),
          isBlockedChat: false, // 是否被屏蔽消息 默认false
          byname: userName, // 备注名就是自己的用户名
        }
      ], // 好友列表
      applyMeFriends: [], // 别人申请添加我为好友
    })

    ctx.body = {
      code: '0000',
      message: '添加成功',
      data: {
        userName,
        uid: r2[0].uid,
        sex: r2[0].sex,
        avatarUrl: r2[0].avatarUrl,
        addDate: Date.now(),
        isBlockedChat: false, // 是否被屏蔽消息 默认false
      }
    }
  } else {
    const isSelfInFriend = r1[0].friends.find(item => item.userName === userName);
    if (isSelfInFriend) {
      ctx.body = {
        code: '0020',
        message: '不能重复添加自己为好友',
        data: false
      }
    } else {
      db2.addDeep('chat', { userName }, {
        friends: {
          userName,
          uid: r2[0].uid,
          sex: r2[0].sex,
          avatarUrl: r2[0].avatarUrl,
          addDate: Date.now(),
          isBlockedChat: false, // 是否被屏蔽消息 默认false
          byname: userName, // 备注名就是自己的用户名
        }
      })

      ctx.body = {
        code: '0000',
        message: '添加成功',
        data: {
          userName,
          uid: r2[0].uid,
          sex: r2[0].sex,
          avatarUrl: r2[0].avatarUrl,
          addDate: Date.now(),
          isBlockedChat: false, // 是否被屏蔽消息 默认false
        }
      }
    }
  }
})

/**
 * 申请添加好友
 * 根据用户名或uid添加用户
 * @param {string} friend 要添加的用户名或uid
 * @param {string} applyWords 申请添加别人为好友时写的申请语
 * @param {string} byname 申请或者接受申请时，给好友起的备注名
 */
router.post('/addFriend', async (ctx, next) => {
  const userName = ctx.request.header.username;
  const { friend, applyWords, byname } = ctx.request.body;
  if (!friend) {
    ctx.body = {
      code: '0002',
      msg: '缺少必要参数',
      data: null
    }
    return;
  }
  const r0 = await db2.find('users', { $or: [{ userName: friend }, { uid: parseInt(friend) }] });
  if (!r0 || r0.length === 0) {
    ctx.body = {
      code: '0013',
      msg: '用户不存在',
      data: null
    }
    return;
  }
  const friendInfo = r0[0];
  const r1 = await db2.find('chat', { userName });
  const r2 = await db2.find('users', { userName });
  if(r1 && r1.length > 0) {
    if (r1[0].applyOtherUserFriends.length >= 100) {
      ctx.body = {
        code: '0024',
        message: '申请添加好友人数已达上限',
        data: false
      }
      return;
    }
    if (r1[0].friends.length >= 500) {
      ctx.body = {
        code: '0026',
        message: '你的好友人数已达上限',
        data: false
      }
      return;
    }
    const applyMe = r1[0].applyMeFriends.find(item => item.userName === r0[0].userName);
    if (applyMe) {
      ctx.body = {
        code: '0020',
        message: '该用户已申请添加你为好友',
        data: false
      }
      return;
    }
    const applyFriend = r1[0].applyOtherUserFriends.filter(item => item.userName === friend || item.uid === parseInt(friend));
    if (applyFriend.length > 0) { // 之前申请加过该用户好友
      if (Date.now() - applyFriend[0].addDate <= 30 * 24 * 3600 * 1000) { // 没超过限定时间
        if (applyFriend[0] >= 6) { // 超次数
          ctx.body = {
            code: '0023',
            message: '添加次数超限',
            data: null
          }
          return;
        } else { // 没超次数
          await db2.updateDeepKey('chat', { userName, 'applyOtherUserFriends.userName': applyFriend[0].userName }, { 'applyOtherUserFriends.$.times': applyFriend[0].times + 1 });
        }
      } else { // 超过限定时间了
        await db2.updateDeepKey('chat', { userName, 'applyOtherUserFriends.userName': applyFriend[0].userName }, { 'applyOtherUserFriends.$.times': 1,  'applyOtherUserFriends.$.addDate': Date.now()});
      }
    } else { // 之前没申请过加该用户为好友
      await db2.addDeep('chat', { userName }, {
        applyOtherUserFriends: { 
          userName: friendInfo.userName,
          uid: friendInfo.uid,
          sex: friendInfo.sex,
          avatarUrl: friendInfo.avatarUrl,
          addDate: Date.now(), 
          times: 1,
          applyWords: applyWords || `我是${userName}`,
          byname: byname || friendInfo.userName,
      }})
    }
  }

  const r3 = await db2.find('chat', { userName: r0[0].userName });
  if (!r3 || r3.length === 0) {
    await db2.addOne('chat', {
      userName: r0[0].userName,
      uid: r0[0].uid,
      sex: r0[0].sex,
      avatarUrl: r0[0].avatarUrl,
      feelingWords: '', // webchat签名状态
      applyOtherUserFriends: [],
      groups: [], 
      friends: [], 
      applyMeFriends: [ 
        {
          userName,
          uid: r2[0].uid,
          sex: r2[0].sex,
          avatarUrl: r2[0].avatarUrl,
          applyMeDate: Date.now(),
          applyWords: applyWords || `我是${userName}`, // 申请语
        }
      ], 
    })
  } else {
    if (r3[0].friends.length >= 500) {
      ctx.body = {
        code: '0025',
        message: '对方好友人数已达上限',
        data: false
      }
      return;
    }
    if (r3[0].applyMeFriends.length >= 100) {
      ctx.body = {
        code: '0027',
        message: '对方被申请人数已达上限',
        data: false
      }
      return;
    }
    const r4 = await db2.find('chat', { userName: r0[0].userName, 'applyMeFriends.userName': userName });
    if (!r4 || r4.length === 0) {
      await db2.addDeep('chat', { userName: r0[0].userName }, {
        applyMeFriends: {
          userName,
          uid: r2[0].uid,
          sex: r2[0].sex,
          avatarUrl: r2[0].avatarUrl,
          applyMeDate: Date.now(),
          applyWords: applyWords || `我是${userName}`, // 申请语
      }})
    }
  }

  ctx.body = {
    code: '0000',
    message: 'ok',
    data: true
  }
})

/**
 * 申请添加我为好友的列表
 */
router.get('/applyMeFriends', async (ctx, next) => {
  const userName = ctx.request.header.username;
  const r0 = await db2.find('chat', { userName });
  ctx.body = {
    code: '0000',
    message: 'ok',
    data: r0[0]?.applyMeFriends ?? []
  }
})

/**
 * 我的好友列表
 */
router.get('/myFriendsList', async (ctx, next) => {
  const userName = ctx.request.header.username;
  const r = await db2.find('chat', { userName });

  const r1 = r[0]?.friends ?? [];
  for (const friend of r1) {
    const r2 = await db2.find('chatMessages', { 'to.userName': userName, 'from.userName': friend.userName, isRead: false });
    // 未读消息数量
    friend.notReadCount = r2?.length || 0;
  }

  ctx.body = {
    code: '0000',
    message: 'ok',
    data: r1
  }
})

/**
 * 接受别人申请添加我为好友
 */
router.post('/acceptOtherApply', async (ctx, next) => {
  const userName = ctx.request.header.username;
  const { uname, byname } = ctx.request.body;
  const r0 = await db2.find('chat', { userName });
  const info = r0[0].applyMeFriends.find(item => item.userName === uname);
  if (!info || Object.keys(info).length === 0) {
    ctx.body = {
      code: '0020',
      message: '已经是好友啦~',
      data: false
    }
    return;
  }
  const r1 = await db2.find('chat', { userName: uname });
  const applyOther = r1[0].applyOtherUserFriends.find(item => item.userName === userName);
  await db2.deleteDeep('chat', { userName: uname }, { applyOtherUserFriends: { userName } });
  await db2.deleteDeep('chat', { userName }, { applyMeFriends: { userName: uname } });
  await db2.addDeep('chat', { userName }, { friends: { ...info, byname: byname || uname, beFriendDate: Date.now(), isBlockedChat: false, } });
  await db2.addDeep('chat', { userName: uname }, { friends: { ...applyOther, beFriendDate: Date.now(), isBlockedChat: false, } });
  ctx.body = {
    code: '0000',
    message: 'ok',
    data: true
  }
})

/**
 * 分页获取和某个好友的聊天消息
 * @param {string} chater 聊天对象的用户名
 * @param {number} page 页数 从第一页开始
 */
const PAGE_SIZE = 200; // 每页200条
router.get('/getChatMsgWithFriend', async (ctx, next) => {
  const userName = ctx.request.header.username;
  const { chater, page } = ctx.query;
  if (!chater) {
    ctx.body = {
      code: '0002',
      message: '缺少必要参数',
      data: false
    }
    return;
  }
  const r0 = await db2.findCriteria('chatMessages', [{ $match: { $or: [{ 'from.userName': userName, 'to.userName': chater, isDeleted: { $ne: true } }, { 'from.userName': chater, 'to.userName': userName }] } }, { $sort: { date: -1 } }, { $skip: (page ? (page - 1) : 0) * PAGE_SIZE }, { $limit: PAGE_SIZE }]);
  const sortR = r0.sort((a, b) => (a.date - b.date));
  const result = [];
  sortR.forEach(item => {
    if (item.isShowDate) {
      result.push({
        date: item.date,
        messageType: 'DATE'
      });
      result.push(item);
    } else {
      result.push(item);
    }
  })
  ctx.body = {
    code: '0000',
    message: '查询成功',
    data: result
  }
})

/**
 * 将来自某个用户的聊天消息都设置为已读
 */
router.post('/setChaterMessageRead', async (ctx, next) => {
  const userName = ctx.request.header.username;
  const { chater } = ctx.request.body;
  if (!chater) {
    ctx.body = {
      code: '0002',
      message: '缺少必要参数',
      data: false
    }
    return;
  }
  await db2.updateManyKey('chatMessages', { 'from.userName': chater, 'to.userName': userName }, { isRead: true });
  const r = await db2.find('chat', { userName });
  const { friends } = r[0];
  ctx.body = {
    code: '0000',
    message: '设置已读成功',
    data: friends
  }
})

/**
 * 删除某条消息
 * @param {string} messageId 消息id
 * @param {string} chater 聊天对象的userName
 */
router.post('/deleteTheMessage', async (ctx, next) => {
  const userName = ctx.request.header.username;
  const { messageId, chater } = ctx.request.body;
  if (!messageId || !chater) {
    ctx.body = {
      code: '0002',
      message: '缺少必要参数',
      data: false
    }
    return;
  }
  await db2.updateKey('chatMessages', { 'from.userName': userName, 'to.userName': chater, messageId }, { isDeleted: true });

  const r0 = await db2.findCriteria('chatMessages', [{ $match: { $or: [{ 'from.userName': userName, 'to.userName': chater, isDeleted: { $ne: true } }, { 'from.userName': chater, 'to.userName': userName }] } }, { $sort: { date: -1 } }, { $skip: 0 }, { $limit: PAGE_SIZE }]);
  const sortR = r0.sort((a, b) => (a.date - b.date));
  const result = [];
  sortR.forEach(item => {
    if (item.isShowDate) {
      result.push({
        date: item.date,
        messageType: 'DATE'
      });
      result.push(item);
    } else {
      result.push(item);
    }
  })

  ctx.body = {
    code: '0000',
    message: '删除成功',
    data: result
  }
})

/**
 * 修改好友备注名称
 * @param {string} chater 聊天对象的userName
 */
router.post('/motifyChaterByname', async (ctx, next) => {
  const userName = ctx.request.header.username;
  const { chater, newName } = ctx.request.body;
  if (!chater || !newName) {
    ctx.body = {
      code: '0002',
      message: '缺少必要参数',
      data: false
    }
    return;
  }

  await db2.updateDeepKey('chat', { userName, 'friends.userName': chater }, { 'friends.$.byname': newName });

  const r = await db2.find('chat', { userName });
  const f = r[0]?.friends || [];

  ctx.body = {
    code: '0000',
    message: '修改成功',
    data: f
  }
})

/**
 * 消息免打扰 / 开启新消息提醒
 * @param {string} chater 聊天对象的userName
 * @param {boolean} isBlocked true：消息免打扰 false：开启新消息提醒 默认为true
 */
router.post('/isSetChaterBlocked', async (ctx, next) => {
  const userName = ctx.request.header.username;
  const { chater, isBlocked } = ctx.request.body;
  if (!chater) {
    ctx.body = {
      code: '0002',
      message: '缺少必要参数',
      data: false
    }
    return;
  }
  await db2.updateDeepKey('chat', { userName, 'friends.userName': chater }, { 'friends.$.isBlockedChat': isBlocked || false });
  ctx.body = {
    code: '0000',
    message: '设置成功',
    data: {
      userName: chater,
      isBlockedChat: isBlocked || false
    }
  }
})

/**
 * 删除和某人的聊天消息 此时不显示和某个用户的聊天消息 最后消息 以及以往消息记录
 */

module.exports = router